package com.str.utils;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import com.str.dto.SmsCodeVerifyDto;
import com.str.pojo.Sms;
import com.str.vo.ResponseVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: ZhangWu, Anything is possible!
 * @CreateTime: 2023/04/09 21:31
 * @Description: 阿里云发送短信服务utils
 */
@Log4j2
@Component
public class SendSmsUtils {

    private static String SMS_SUCCESS_CODE = "OK";

    @Value("${alibaba.sms.templateCode}")
    private String templateCode;

    @Value("${alibaba.sms.accessKeyId}")
    private String accessKeyId;

    @Value("${alibaba.sms.secret}")
    private String secret;

    @Value("${alibaba.sms.signName}")
    private String signName;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 发送短信
     *
     * @param sms
     * @return
     */
    public ResponseVO sendSmsCode(Sms sms) {
        String redisKey = sms.getPhoneNumbers() + "_"  + "_code";
        // 从redis中获取该手机号码该模板3分钟内是否发送成功过短信，如果发送成功过，不在发送
        String redisCode = redisUtil.get(redisKey, String.class);
        if (StringUtils.isEmpty(redisCode)) {
            String verifyCode = String.valueOf((int) (Math.random() * 900000 + 100000));
            JSONObject json = new JSONObject();
            json.put("code", verifyCode);
            sms.setTemplateParam(json.toJSONString());
            ResponseVO sendResult = sendSmsRequest(sms);
            if (Retcode.SUCCESS.code().equals(sendResult.getRetcode())) {
                redisUtil.set(redisKey, verifyCode, 120);
                return new ResponseVO(verifyCode);
            }
            return sendResult;
        } else {
            return new ResponseVO(redisCode);
        }
    }

    /**
     * 发送短信验证码
     *
     * @param smsCodeVerifyDto
     * @return
     */
    public ResponseVO verifySmsCode(SmsCodeVerifyDto smsCodeVerifyDto) {
        String code = smsCodeVerifyDto.getCode();
        if (StringUtils.isEmpty(smsCodeVerifyDto.getPhoneNumbers())) {
            return new ResponseVO(Retcode.SMS_VERIFY_PHONE_NULL.code(), Retcode.SMS_VERIFY_PHONE_NULL.msg(), null);
        }
        if (StringUtils.isEmpty(code)) {
            return new ResponseVO(Retcode.SMS_VERIFY_CODE_NULL.code(), Retcode.SMS_VERIFY_CODE_NULL.msg(), null);
        }
        return sendSmsRequest(new Sms().setTemplateParam(smsCodeVerifyDto.getCode())
                .setPhoneNumbers(smsCodeVerifyDto.getPhoneNumbers()));
    }

    /**
     * 发送短信请求
     *
     * @param sms
     * @return
     */
    private ResponseVO sendSmsRequest(Sms sms) {
        Map<String, String> param = new HashMap<>();
        param.put("code",sms.getTemplateParam());
        DefaultProfile profile = DefaultProfile.getProfile("default", accessKeyId, secret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.putQueryParameter("PhoneNumbers", sms.getPhoneNumbers());
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));
        try {
            CommonResponse response = client.getCommonResponse(request);
            if (response == null) {
                return new ResponseVO(Retcode.SMS_SEND_EXCEPTION.code(), Retcode.SMS_SEND_EXCEPTION.msg(), null);
            }
            log.info("给{}发送短信返回结果：{}", sms.getPhoneNumbers(), new Gson().toJson(response));

            JSONObject data = JSONObject.parseObject(response.getData());
            String bizId = null;
            String message = data.getString("Message");
            String code = data.getString("Code");
            if (SMS_SUCCESS_CODE.equals(code)) {
                code = Retcode.SUCCESS.code();
                bizId = data.getString("BizId");
            }
            return new ResponseVO(code, message, bizId);
        } catch (ServerException e) {
            log.error("给 " + sms.getPhoneNumbers() + "发送短信ServerException：", e);
        } catch (ClientException e) {
            log.error("给" + sms.getPhoneNumbers() + "发送短信ClientException：", e);
        }
        return new ResponseVO(Retcode.SMS_SEND_EXCEPTION.code(), Retcode.SMS_SEND_EXCEPTION.msg(), null);

    }

    public static void main(String[] args) {

    }
}
